<?php

/**
 * 
 * @see Lite_Collection_SortedSequence
 */
class Lite_Collection_ArraySortedSet
	extends Lite_Collection_AbstractCollection
	implements Lite_Collection_SortedSet {
	
	/**
	 * @param LiteCollection LiteCollection LiteCollection $colA
	 * @param LiteCollection LiteCollection LiteCollection $colB
	 * @return LiteCollection
	 */
	static function union(LiteCollection $colA, LiteCollection $colB){
		return self::unionInto(new self, $colA, $colB);
	}
	
	/**
	 * @var Lite_Collection_Comparator
	 */
	private $comparator;
	
	/**
	 * @var Lite_Collection_Sequence
	 */
	private $sequence;
	
	/**
	 * @param Lite_Collection_Comparator
	 */
	function setComparator(Lite_Collection_Comparator $comparator) {
		$this->comparator = $comparator;
	}
	
	/**
	 * @return Lite_Collection_Comparator
	 */
	function getComparator() {
		if( null === $this->comparator ) {
			$this->comparator = new Lite_Collection_NaturalComparator();
		}
		return $this->comparator;
	}
	
	private function getSequence() {
		if( null === $this->sequence ) {
			$this->sequence = new Lite_Collection_ArraySequence();
		}
		return $this->sequence;
	}
	
	/**
	 * @throws Lite_Collection_NoSuchElementException
	 */
	public function first(){
		$this->throwIfEmpty();
		return reset($this->toArray());
	}

	/**
	 * @throws Lite_Collection_NoSuchElementException
	 */
	public function last(){
		$this->throwIfEmpty();
		return end($this->toArray());
	}

	/**
	 * @throws Lite_Collection_NoSuchElementException
	 */
	private function throwIfEmpty() {
		if( $this->isEmpty() ) {
			throw new Lite_Collection_NoSuchElementException('The set is empty');
		}
	}
	/**
	 * 
	 */
	public function clear(){
		if( null !== $this->sequence ) {
			$this->sequence->clear();
		}		
	}

	/**
	 * @param unknown_type $element
	 */
	public function add($anElement){
		$sequence = $this->getSequence();
		
		if($sequence->contains($anElement)) {
			return;
		}
		
		$comparator = $this->getComparator();
		
		$i = 0;
		foreach( $sequence as $i => $elem ) {
			if( $comparator->compareTo($elem, $anElement) != -1 ) {
				break;
			}
		}
		$sequence->addAt( $i, $anElement );
	}

	/**
	 * @param unknown_type $element
	 */
	public function contains($element){
		if( null !== $this->sequence ) {
			return $this->sequence->contains($element);
		}
		return false;		
	}

	/**
	 * @param mixed $element
	 */
	public function remove($element){
		if( null !== $this->sequence ) {
			$this->sequence->remove($element);
		}
	}

	/**
	 * @return array
	 */
	public function toArray(){
		$set = $this->getSequence();
		return $set->toArray();				
	}

}